public class SP_Trigger{
    public class SPValidationException extends Exception {}
    public enum SPType { MASP,NCSP } 
    
    public static boolean DefEntHintUnlocked = false; // Only the Entitlements update/delete triggers can unlock
 
     // Validates the SP as either MASP or NCSP
    public static void ValidateSP(Support_Program__c sp, SPType spt) 
    {
        // Preconditions that must be set by the direct caller cause exceptions.
        // Invariants that indicate bad data (but not responsibiliy of caller) use sp.addError()

        if (spt==SPType.NCSP) {
            if (sp.Account__c==null) {
                sp.addError('Invalid NCSP.  In a Named Caller model, the SP.Account field is never left blank, since SPs are unique to a single Account.');
                return;
            }
        } else {
            if (sp.Account__c!=null) { throw new SPValidationException('Invalid MASP.  In a Multi-Account SP model, the SP.Account field must be blank, because the Accounts themselves point to a single SP through their Account.SP field.'); }
            if (sp.Apply_To_All_Contacts_In_Account__c==False) { throw new SPValidationException('Invalid MASP.  In a Multi-Account SP model, all Contacts within a covered Account are treated the same way by definition; therefore, the Apply To All box is always checked.'); }        
        }
    }

    static testMethod void testValidateSP_ShouldFailMASP1() 
    {
        UT_SObjectFactory.InterconnectedSObjectsForMASP o = 
            new UT_SObjectFactory.InterconnectedSObjectsForMASP(5);
        Account a = new Account(Name='UNITTEST-ACCT'); insert a;
        o.sp.Account__c = a.Id;
        try { SP_Trigger.ValidateSP(o.sp,SPType.MASP); } catch(Exception e) { return; }
        system.assert(false,'Should have thrown for unchecked box');
    }

    static testMethod void testValidateSP_ShouldFailMASP2() 
    {
        UT_SObjectFactory.InterconnectedSObjectsForMASP o = 
            new UT_SObjectFactory.InterconnectedSObjectsForMASP(5);
        o.sp.Apply_To_All_Contacts_In_Account__c = false;
        try { SP_Trigger.ValidateSP(o.sp,SPType.MASP); } catch(Exception e) { return; }
        system.assert(false,'Should have thrown for unchecked box');
    }    
}